﻿#ifndef XQTHREADLIST_H
#define XQTHREADLIST_H
#include<atomic>
#include<QReadWriteLock>
#include<list>
//线程安全链表
template<typename T>
class XQThreadList
{
public:
	void push_back(const T& val);//尾插
	void push_front(const T& val);//头插
	T pop_front();//尾删返回原尾
	T pop_back();//头删返回原头
public:
	//查询返回迭代器
	auto find(T& val);
	//删除元素迭代器
	template <typename It>
	auto erase(It it);
	auto begin();
	auto end();
public:
	//判断是否存在
	bool isExist(const T& val);
	//删除成功返回true
	bool remove(const T& val);
	template <typename _Pr1>
	//删除成功返回true
	bool remove_if(_Pr1 _Pred);
public:
	size_t size();
	bool isEmpty();
	void clear();
	const T& back();
	const T& front() ;
public:
	XQThreadList<T>& operator<<(const T& val);
public:
	QReadWriteLock* lock();//返回内部读写锁
	std::list<T>& list();//返回内部链表
protected:
	QReadWriteLock m_lock;
	std::list<T> m_list;
};
template<typename T>
inline void XQThreadList<T>::push_back(const T& val)
{
	QWriteLocker Lock(&this->m_lock);
	this->m_list.push_back(val);
}
template<typename T>
inline void XQThreadList<T>::push_front(const T& val)
{
	QWriteLocker Lock(&m_lock);
	this->m_list.push_front(val);
}

template<typename T>
inline T XQThreadList<T>::pop_front()
{
	QWriteLocker Lock(&m_lock);
	T val = this->m_list.front();
	this->m_list.pop_front();
	return std::move(val);
}
template<typename T>
inline T XQThreadList<T>::pop_back()
{
	QWriteLocker Lock(&m_lock);
	T val = this->m_list.back();
	this->m_list.pop_back();
	return std::move(val);
}

template<typename T>
inline auto XQThreadList<T>::find(T& val)
{
	QReadLocker Lock(&m_lock);
	return static_cast<std::list<T>::iterator>(std::find(this->m_list.begin(), this->m_list.end(), val));
}

template<typename T>
inline auto XQThreadList<T>::begin()
{
	QReadLocker Lock(&m_lock);
	return static_cast<std::list<T>::iterator>(this->m_list.begin());
}

template<typename T>
inline auto XQThreadList<T>::end()
{
	QReadLocker Lock(&m_lock);
	return static_cast<std::list<T>::iterator>(this->m_list.end());
}

template<typename T>
bool XQThreadList<T>::isExist(const T& val)
{
	QReadLocker Lock(&this->m_lock);
	if (m_list.empty())
		return false;
	auto it = std::find(this->m_list.begin(), this->m_list.end(), val);
	return it != static_cast<decltype(it)>(this->m_list.end());
}

template<typename T>
inline bool XQThreadList<T>::remove(const T& val)
{
	QWriteLocker Lock(&m_lock);
	auto it = std::find(this->m_list.begin(), this->m_list.end(), val);
	if (it == static_cast<decltype(it)>(this->m_list.end()))
		return false;
	this->m_list.erase(it);
	return true;
}

template<typename T>
inline size_t XQThreadList<T>::size() 
{
	QReadLocker Lock(&m_lock);
	return this->m_list.size();
}

template<typename T>
inline bool XQThreadList<T>::isEmpty() 
{
	QReadLocker Lock(&m_lock);
	return this->m_list.empty();
}

template<typename T>
inline void XQThreadList<T>::clear()
{
	QWriteLocker Lock(&m_lock);
	this->m_list.clear();
}

template<typename T>
inline const T& XQThreadList<T>::back() 
{
	QReadLocker Lock(&m_lock);
	return this->m_list.back();
}

template<typename T>
inline const T& XQThreadList<T>::front() 
{
	QReadLocker Lock(&m_lock);
	return this->m_list.front();
}

template<typename T>
inline XQThreadList<T>& XQThreadList<T>::operator<<(const T& val)
{
	push_back(val);
	return *this;
}

template<typename T>
inline QReadWriteLock* XQThreadList<T>::lock()
{
	return &m_lock;
}

template<typename T>
inline std::list<T>& XQThreadList<T>::list()
{
	return this->m_list;
}

template<typename T>
template<typename It>
inline auto XQThreadList<T>::erase(It it)
{
	QWriteLocker Lock(&m_lock);
	return static_cast<std::list<T>::iterator>(this->m_list.erase(it));
}

template<typename T>
template<typename _Pr1>
inline bool XQThreadList<T>::remove_if(_Pr1 _Pred)
{
	QWriteLocker Lock(&m_lock);
	auto it = std::find_if(this->m_list.begin(),this->m_list.end(), _Pred);
	if (it == static_cast<decltype(it)>(this->m_list.end()))
		return false;
	this->m_list.erase(it);
	return true;
}
#endif